home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / DEVELOP.ZIP / USERSYS.DOC < prev   
Text File  |  1996-07-23  |  35KB  |  696 lines

  1.   WARNING:  This document is subject to change at any time.  Any changes made
  2.   will be indicated by a vertical bar (|) in column 1 of the file.
  3.  
  4. | Last update: 07/23/96
  5.  
  6. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  7.  
  8.  
  9.                   WHAT ARE THE USERS.SYS AND USERS.INF FILES
  10.                   ------------------------------------------
  11.  
  12.   The USERS.INF file is an extension to the USERS file.  It is generally
  13.   accessed solely by PCBoard software with third party software utilizing
  14.   the USERS.SYS file instead.
  15.  
  16.   The USERS.SYS file is a "single source" for everything you need to know
  17.   about the caller that is online.  It is created by PCBoard - but may be
  18.   UPDATED by a door or utility program.
  19.  
  20.  
  21.                            USERS.INF BRIEF OVERVIEW
  22.                            ------------------------
  23.  
  24.   The USERS.INF file layout boasts some pretty high limits that hopefully
  25.   will take the software through the next few years without major
  26.   modifications.  For example, the following capabilities exist within the
  27.   file structure:
  28.  
  29.   * A variable number of conferences ranging from 0 to 65495 - with the other
  30.     40 conferences being stored in the main USERS file.
  31.  
  32.   * A variable sized PCBoard record which will allow for growth in the future
  33.     without causing major upgrade problems with file formats are changed.
  34.  
  35.   * A variable number of installable Third Party Applications (from 0 - 65535)
  36.     providing KEYWORD access to the applications and permitting the application
  37.     to "piggy back" its user record needs onto the USERS.INF file while
  38.     allowing PCBoard software to performance the maintenance on the file.
  39.  
  40.   * Variable sized records for Third Party Applications allowing each Third
  41.     Party Application to use up only what it needs - or as much as it needs.
  42.  
  43.   In essence, PCBoard will have the file layout capability for as many as
  44.   65,535 conference areas (though the software may lag behind the file
  45.   layout's capabilities for some time due to memory constraints as well as
  46.   user interface problems - but those can be dealt with later on).
  47.  
  48.   It will also allow Third Party Authors to install their software (using a
  49.   PCBSM) into PCBoard's system files - that is, the Third Party Software
  50.   could actually store their own information inside of PCBoard's USERS.INF
  51.   file by telling PCBoard that they are there and how much file space they
  52.   need.  This way PCBoard and its utilities would be able to help out with
  53.   maintenance of the file such as adding in new records or deleting existing
  54.   records, etc.
  55.  
  56.   Additionally, when PCBoard opens a door it will check the name of the
  57.   door against the KEYWORD used in the TPA header to determine if the
  58.   USERS.SYS file should include a TPA record.
  59.  
  60.  
  61.                            USERS.SYS BRIEF OVERVIEW
  62.                            ------------------------
  63.  
  64.   The USERS.SYS file is the one that DOOR and UTILITY authors are expected to
  65.   read and write.  It is a "one stop shopping spot" for everything you need
  66.   to know about the user that is currently online.  The DOOR or UTILITY
  67.   author can feel free to update the USERS.SYS file and any changes made to
  68.   the user record (whether PCBoard's own user record or the TPA user records
  69.   in the file) will be automatically posted to the appropriate files when
  70.   PCBoard reloads.
  71.  
  72.   Because the information in the USERS.SYS file is derived from a combination
  73.   of the USERS and USERS.INF file - it contains the same flexibility for
  74.   growth and capabilities as described above regarding the USERS.INF file.
  75.  
  76.   The file layout itself includes a header record that describes the size of
  77.   the PCBoard user record and the name of the TPA and its record size (if
  78.   any).  The header record should be inspected first to determine how much of
  79.   the file should be read in (you may not need to read the whole file - only
  80.   that which is necessary for your own operation) and how much should be
  81.   updated if you are going to make any changes to the file.
  82.  
  83.  
  84.                              USERS.INF FILE LAYOUT
  85.                              ---------------------
  86.  
  87.   NOTE:  it is recommended that people access only the USERS.SYS file and not
  88.   touch the USERS.INF leaving that job up to PCBoard.  However, in the case
  89.   where an application may need to globally modify the records that belong
  90.   to it in the USERS.INF file it may be necessary to know a little about the
  91.   header record and how to get to the Third Party Application records.
  92.  
  93.   The file layout comes in 4 separate parts.  They are:
  94.  
  95.   1) A header describing PCBoard's file allocation requirements
  96.   2) A header describing each of the TPA file allocation requirements
  97.   3) The PCBoard User Record
  98.   4) Each of the TPA extensions to the PCBoard User Record
  99.  
  100.   Knowing the above you can determine the total HEADER size (comprised of
  101.   parts 1 and 2 above) by calculating the size of the PCBoard header then
  102.   adding to that the size of the application header multiplied by the number
  103.   of applications.
  104.  
  105.   Determining the user record size is similarly accomplished by adding the
  106.   size of PCBoard's data record together with all of the data records
  107.   specified by the application headers.
  108.  
  109.   Examples of the above will be provided down below following the formal file
  110.   formats.
  111.  
  112.                           USERS.INF RECORD STRUCTURES
  113.                           ---------------------------
  114.  
  115.   typedef struct {
  116.     unsigned Version;        PCBoard Version Number
  117.     unsigned NumOfConf;      Number of EXTENDED Conferences Allocated in File
  118.     unsigned SizeOfRec;      Size of the 'static' PCBoard User Record
  119.     long     SizeOfConf;     Total Size of PCBoard Conference Information
  120.     unsigned NumOfApps;      Number of Third Party Apps adding onto the record
  121.     long     TotalRecSize;   Total Record Size (PCB and all TPA components)
  122.   } hdrtype;
  123.  
  124.   typedef struct {
  125.     char     Name[15];       Name of Application (NULL terminated)
  126.     unsigned Version;        Version Number
  127.     unsigned SizeOfRec;      Size of Application Record information (0-65535)
  128.     unsigned SizeOfConfRec;  Size of Conference Record information (0-65535)
  129.     char     KeyWord[9];     Keyword to execute Application (NULL terminated)
  130.     long     Offset;         Offset in User Record where TPA record begins
  131.   } apptype;
  132.  
  133.  
  134.                               ACCESSING THE FILE
  135.                               ------------------
  136.  
  137.   Accessing the file comes in two steps.  One is in reading the file header
  138.   which can be done upon program initialization - and the other is in
  139.   locating a specific user record.
  140.  
  141.   Step 1:  Read the HEADER record to determine (1) how big the header is
  142.            and (2) how big each record is.
  143.  
  144.            To determine how big the header is you multiply the number of
  145.            TPA's by the size of the Application Header record and add to
  146.            that the size of the main Header record.
  147.  
  148.            Example:
  149.            HdrSize = sizeof(hdrtype)+(Hdr.NumOfApps * sizeof(apptype));
  150.  
  151.            The size of each record is stored in the header itself.
  152.  
  153.    Step 2: Using the information gathered in step 1 above it's fairly easy
  154.            to get to the actual user record.  For example, if you wanted to
  155.            read the information in a user record you would use the following
  156.            code:
  157.  
  158.            lseek(File,(RecNum-1)*TotalRecSize + HdrSize,SEEK_SET);
  159.  
  160.            In other words, you would calculate the record number minus 1 and
  161.            multiply it by the total user record size as determined in step 1
  162.            and add to that the size of the header record.  Moving the disk
  163.            head to this position sets you up to read the PCBoard user record.
  164.  
  165.            If you wanted to skip over the PCBoard component of the user
  166.            record then you would simply add the OFFSET of the TPA record into
  167.            the equation like this:
  168.  
  169.            lseek(File,(RecNum-1)*TotalRecSize + HdrSize + Offset,SEEK_SET);
  170.  
  171.            RecNum will be a LONG integer stored at offset 385 in the USERS
  172.            file (i.e.  bytes 385, 386, 387 and 388 comprise the RECNUM which
  173.            will be used to access the USERS.INF file).
  174.  
  175.  
  176.   This file layout and accessing methodology, though somewhat complicated,
  177.   gives the following benefits:
  178.  
  179.   - Because the PCBoard data size is determined by a field in the header
  180.     it is therefore allowed to GROW at will - that is to say, when
  181.     PCBoard needs new fields it can add those fields into the record and
  182.     adjust the file format without breaking Third Party Software that is
  183.     already coded to read and use the USERS.INF file.
  184.  
  185.   - Because the number of conferences is specified in the header the
  186.     sysop will have the ability to grow or shrink his USERS.INF file
  187.     according to his needs as he adds or removes conferences.
  188.  
  189.   - Because the header also accounts for Third Party Applications and
  190.     their needs it will allow Third Party Authors to more easily install
  191.     their software into a PCBoard system and then let PCBoard take care
  192.     of adding and removing user records.  This also saves storing yet
  193.     another file on disk that may be redundant in nature compared to
  194.     similar files used by similar Third Party programs.
  195.  
  196.  
  197.   THE PCBOARD RECORD IN THE USERS.INF FILE
  198.   ----------------------------------------
  199.   It is preferable that Third Party Applications do *not* access the PCBoard
  200.   data area within the USERS.INF file if it can be avoided for the the simple
  201.   reason that PCBoard may expand on it and access to USERS.SYS is recommended
  202.   instead.  However, the following information provides details as to how the
  203.   PCBoard data record is CURRENTLY formatted:
  204.  
  205.   typedef struct {
  206.     char     Name[25];    User Name (in case connection to USERS is lost)
  207.     long     MsgsRead;    Number of messages the user has read in PCBoard
  208.     long     MsgsLeft;    Number of messages the user has left in PCBoard
  209.   } rectype;
  210.  
  211.   The above is the current format of the STATIC portion of the the PCBoard
  212.   record.  The size of which is specified in the USERS.INF header field
  213.   hdrtype.SizeOfRec.
  214.  
  215.   The conference record is much more difficult to access and cannot be
  216.   described by a fixed typedef structure.  The following two calculations
  217.   are required before you'll be able to read the file:
  218.  
  219.     ConfByteLen = (NumAreas / 8) + ((NumAreas % 8) != 0 ? 1 : 0);
  220.     if (ConfByteLen < 5)
  221.       ConfByteLen = 5;
  222.  
  223.     ExtConfLen = ConfByteLen - 5;
  224.  
  225.   In the conference record you will then find 5 bit map fields in the following
  226.   order:
  227.  
  228.     1) Mail Waiting Flags            (length is ConfByteLen bytes long)
  229.     2) Conference Sysop Flags        (length is ConfByteLen bytes long)
  230.     3) Registered In Conference      (length is ExtConfLen bytes long)
  231.     4) Exp. Conference Registrations (length is ExtConfLen bytes long)
  232.     5) Conference Scan Preference    (length is ExtConfLen bytes long)
  233.  
  234.   Note that ConfByteLen will always be at least 5.  While ExtConfLen can be 0
  235.   bytes in length if the number of conferences on the system is 39 or less.
  236.   The reason is because fields 3, 4 and 5 are already contained within the
  237.   USERS file for conferences 0 thru 39.
  238.  
  239.   Immediately following the above structure are the Last Message Read pointers.
  240.   The number of which can be 0 (if 39 conferences or less) or more if there are
  241.   conferences beyond 39.  Each Last Message Read pointer is a long integer.
  242.  
  243.   A note on the usage of the Registered and Expired Registration flags:
  244.  
  245.   PCBoard will turn the REGISTERED flag off while leaving the EXPIRED
  246.   registration flag turned on to indicate that the caller is locked out.
  247.   Examples:
  248.  
  249.    Registered  Expired     PCBoard Shows  Explanation
  250.    ----------  -------  =  -------------  -----------
  251.        Off       Off           ""         Caller is not registered but
  252.                                           may join if the conference is
  253.                                           public and his security level
  254.                                           permits access.
  255.  
  256.        On        Off           "R"        Caller is registered in this
  257.                                           conference. If he expires then
  258.                                           he can no longer access it
  259.                                           unless it is public and his
  260.                                           security level permits access.
  261.  
  262.        On        On     =      "RX"       Caller is always registered.
  263.  
  264.        Off       On     =      "L"        Caller is locked out and
  265.                                           cannot join the conference
  266.                                           regardless of whether it is
  267.                                           public or not.
  268.  
  269.  
  270.   THE PCBOARD SUPPORTED ALLOCATIONS
  271.   ---------------------------------
  272.   PCBoard may actually have more information in the USERS.INF than just the
  273.   information shown above.  This additional information, called PCBoard
  274.   Supported Allocations (PSAs), however, is treated exactly the same as any
  275.   Third Party Allocations (TPAs) in the file.
  276.  
  277.   The only difference is that PCBoard and PCBSM directly support the PSAs by
  278.   providing access to them instead of merely storing and manipulating them.
  279.  
  280.   For example, the Alias Support PSA holds a caller's alias.  If it is
  281.   installed, then PCBoard will keep track of the caller's alias and PCBSM will
  282.   allow you to see the alias by hitting the F2 function key a couple of times
  283.   while in the Users File Editor.
  284.  
  285.  
  286.   USERS.INF FILE SIZE FORMULA
  287.   ---------------------------
  288.   There has been some demand for a "formula" for easily calculating the final
  289.   size of a USERS.INF file given the known quantities of 1) number of
  290.   conferences, 2) size of TPAs and 3) number of users.  The following formula
  291.   can be used for that purpose:
  292.  
  293.   (( (Conf - 40) * 5                                     )           )
  294.   (( --------------- + (Conf - 40) * 4 + (Conf * TpaDyn) ) + TpaStat ) * Users
  295.   ((       8                                             )           )
  296.  
  297.   Conf    = the number of conferences on the system
  298.   TpaDyn  = the size of all dynamic TPA allocations
  299.   TpaStat = the size of all static TPA allocations
  300.   Users   = the number of users in the system
  301.  
  302.   An example calculation for a system with 1000 conferences and QMAIL4
  303.   installed with 2000 users would be:
  304.  
  305.   (( (1000 - 40) * 5                                )       )
  306.   (( --------------- + (1000 - 40) * 4 + (1000 * 1) ) + 256 ) * 2000  =
  307.   ((       8                                        )       )
  308.  
  309.   (( (960) * 5                    )       )
  310.   (( --------- + (960) * 4 + 1000 ) + 256 ) * 2000  =
  311.   ((    8                         )       )
  312.  
  313.   ((  4800               )       )
  314.   (( ----- + 3840 + 1000 ) + 256 ) * 2000  =
  315.   ((   8                 )       )
  316.  
  317.   ( 600 + 3840 + 1000 + 256 ) * 2000 =
  318.  
  319.   5696 * 2000 =
  320.  
  321.   11,392,000   (plus a small amount of overhead for TPA headers and such)
  322.  
  323.   That's a fairly large file but for 1000 conferences and 2000 users it's quite
  324.   understandable.  Smaller numbers of users and/or conferences will yield much
  325.   smaller figures.  Of all of the allocations the biggest one is the Last
  326.   Message Read pointers which are 4 bytes in size for every conference.  Given
  327.   the above example the LMR pointers make up 3840 bytes of the total 5696 bytes
  328.   per user.
  329.  
  330.  
  331.                               USERS.SYS FILE LAYOUT
  332.                               ---------------------
  333.  
  334.   The structure of the USERS.SYS file is as follows:
  335.  
  336.   1) A header record describing what is contained in the file
  337.   2) A fixed-size user record with PCBoard specific data fields
  338.   3) Last Message Read pointers for conferences
  339.   4) Bit Map fields for conferences (registered, expired, scanned, etc)
  340.   5) The Third Party Application fixed record
  341.   6) The Third Party Application conference records
  342.  
  343.  
  344.   The following C structures are used to implement the above layout:
  345.  
  346.   USERS.SYS HEADER STRUCTURE
  347.   --------------------------
  348.   NOTE:  type "bool" is a character field (i.e. 1 byte in size) with a non-zero
  349.   value meaning TRUE and zero meaning FALSE.
  350.  
  351.   typedef struct {
  352.     unsigned Version;           PCBoard version number (i.e. 1500)
  353.     long     RecNo;             Record number from USER's file
  354.     unsigned SizeOfRec;         Size of "fixed" user record (current size)
  355.     unsigned NumOfAreas;        Number of conference areas (Main=1 thru 65535)
  356.     unsigned NumOfBitFields;    Number of Bit Map fields for conferences
  357.     unsigned SizeOfBitFields;   Size of each Bit Map field
  358.     char     AppName[15];       Name of the Third Party Application (if any)
  359.     unsigned AppVersion;        Version number for the application (if any)
  360.     unsigned AppSizeOfRec;      Size of a "fixed length" record (if any)
  361.     unsigned AppSizeOfConfRec;  Size of each conference record (if any)
  362.     long     AppRecOffset;      Offset of AppRec into USERS.INF record (if any)
  363.     bool     Updated;           TRUE if the USERS.SYS file has been updated
  364.   } syshdrtype;
  365.  
  366.  
  367.   USERS.SYS FIXED USER RECORD STRUCTURES
  368.   --------------------------------------
  369.   typedef struct {               Bit packed flags in the users file
  370.     int Dirty        :1;         Dirty Flag (meaning file has been updated)
  371.     int MsgClear     :1;         User's choice for screen clear after messages
  372.     int HasMail      :1;         Indicates if NEW mail has been left for user
  373.     int DontAskFSE   :1;         Don't ask for if FSE should be used
  374.     int FSEDefault   :1;         Default to FSE
  375.     int ScrollMsgBody:1;         Scroll message body when display messages
  376.     int ShortHeader  :1;         Display short message headers
  377.     int WideEditor   :1;         Use wide (79-column) message editor
  378.   } packedbyte;
  379.  
  380.   typedef struct {               Bit packed flags in the users file
  381.     int UnAvailable:1;           Chat Status (Unavailable if bit is set)
  382. |   int SingleLines:1;           Use SHORT File Descriptions
  383.     int Reserved:6;              RESERVED!  DO NO USE THESE BITS
  384.   } packedbyte2;
  385.  
  386.   typedef struct {               DOS format for bit packed date fields
  387.     int Day   :5;                5 bit integer representing the Day
  388.     int Month :4;                4 bit integer representing the Month
  389.     int Year  :7;                7 bit integer representing the Year MINUS 80
  390.   } datetype;
  391.  
  392.   typedef struct {
  393.     char  Street[2][51];         2 NULL-terminated strings for street address
  394.     char  City[26];              A NULL-terminated string for city
  395.     char  State[11];             A NULL-terminated string for state
  396.     char  Zip[11];               A NULL-terminated string for zip
  397.     char  Country[16];           A NULL-terminated string for country
  398.   } addresstypez;
  399.  
  400.   typedef struct {
  401.     char     Previous[3][13];    3 NULL-terminated strings for last 3 passwords
  402.     unsigned LastChange;         Date of last password change
  403.     unsigned TimesChanged;       Number of times password has been changed
  404.     unsigned ExpireDate;         Expiration date of current password
  405.   } passwordtypez;
  406.  
  407.   typedef struct {
  408.     unsigned FirstDateOn;        First date on, in julian date format
  409.     unsigned NumSysopPages;      Number of times caller paged the sysop
  410.     unsigned NumGroupChats;      Number of times caller entered group chat
  411.     unsigned NumComments;        Number of times caller left comment to sysop
  412.     unsigned Num300;             Number of times caller was on a 300 bps
  413.     unsigned Num1200;            Number of times caller was on a 1200 bps
  414.     unsigned Num2400;            Number of times caller was on a 2400 bps
  415.     unsigned Num9600;            Number of times caller was on a 9600 bps
  416.     unsigned Num14400;           Number of times caller was on a 14400+ bps
  417.     unsigned NumSecViol;         Number of security violations committed
  418.     unsigned NumNotReg;          Number of attempts to join un-reg conference
  419.     unsigned NumReachDnldLim;    Number of times download limit was reached
  420.     unsigned NumFileNotFound;    Number of times download file was not found
  421.     unsigned NumPwrdErrors;      Number of times entered password incorrectly
  422.     unsigned NumVerifyErrors;    Number of times upload verification failed
  423.   } callerstattype;
  424.  
  425.   typedef struct {
  426.     char  Line[5][61];           5 NULL-terminated strings for notes on caller
  427.   } notestypez;
  428.  
  429.   typedef struct {
  430.     double StartingBalance;      Starting Balance
  431.     double StartThisSession;     Balance at login of current session
  432.     double DebitCall;            Charges for calls made to the system
  433.     double DebitTime;            Charges for time spent online
  434.     double DebitMsgRead;         Charges for messages read
  435.     double DebitMsgReadCapture;  Charges for messages captured
  436.     double DebitMsgWrite;        Charges for messages written
  437.     double DebitMsgWriteEchoed;  Charges for messages written (echoed)
  438.     double DebitMsgWritePrivate; Charges for messages written (private)
  439.     double DebitDownloadFile;    Charges for files downloaded
  440.     double DebitDownloadBytes;   Charges for bytes downloaded
  441.     double DebitGroupChat;       Charges for time spent in group chat
  442.     double DebitTPU;             Charges for third party utility usage
  443.     double DebitSpecial;         Charges made via PPEs
  444.     double CreditUploadFile;     Payback for files uploaded
  445.     double CreditUploadBytes;    Payback for bytes uploaded
  446.     double CreditSpecial;        Packback made via PPEs
  447.     char DropSecLevel;           Security level on empty/negative balance
  448.   } accounttype;
  449.  
  450.   typedef struct {
  451.     unsigned MaxMsgs;              Maximum messages desired in QWK packet
  452.     unsigned MaxMsgsPerConf;       Maximum messages per conference
  453.     long     PersonalAttachLimit;  Attach limit on personal messages
  454.     long     PublicAttachLimit;    Attach limit on public (non-personal) msgs
  455.     char     Reserved[18];
  456.   } qwkconfigtype;
  457.  
  458.   typedef struct {
  459.     char           Name[26];           Name (NULL terminated)
  460.     char           City[25];           City (NULL terminated)
  461.     char           Password[13];       Password (NULL terminated)
  462.     char           BusDataPhone[14];   Business or Data Phone (NULL terminated)
  463.     char           HomeVoicePhone[14]; Home or Voice Phone (NULL terminated)
  464.     unsigned       LastDateOn;         Julian date for the Last Date On
  465.     char           LastTimeOn[6];      Last Time On (NULL Terminated)
  466.     bool           ExpertMode;         1=Expert, 0=Novice
  467.     char           Protocol;           Protocol (A thru Z)
  468.     packedbyte     PackedFlags;        Bit packed flags
  469.     datetype       DateLastDirRead;    Date for Last DIR Scan (most recent file)
  470.     int            SecurityLevel;      Security Level
  471.     unsigned       NumTimesOn;         Number of times the caller has connected
  472.     char           PageLen;            Page Length when display data on the screen
  473.     unsigned       NumUploads;         Total number of FILES uploaded
  474.     unsigned       NumDownloads;       Total number of FILES downloaded
  475.     long           DailyDnldBytes;     Number of BYTES downloaded so far today
  476.     char           UserComment[31];    Comment field #1 (NULL terminated)
  477.     char           SysopComment[31];   Comment field #1 (NULL terminated)
  478.     int            ElapsedTimeOn;      Number of minutes online
  479.     unsigned       RegExpDate;         Julian date for Registration Expiration Date
  480.     int            ExpSecurityLevel;   Expired Security Level
  481.     unsigned       LastConference;     Number of the conference the caller was in
  482. |   long           ulTotDnldBytes;     Total number of BYTES downloaded  (no longer used - see TotDnldBytes below)
  483. |   long           ulTotUpldBytes;     Total number of BYTES uploaded    (no longer used - see TotUpldBytes below)
  484.     bool           DeleteFlag;         1=delete this record, 0=keep
  485.     long           RecNum;             Record Number in USERS.INF file
  486.     packedbyte2    Flags;              More bit packed flags
  487.     char           Reserved[8];        Bytes 390-397 from the USERS file
  488.     long           MsgsRead;           Number of messages the user has read in PCB
  489.     long           MsgsLeft;           Number of messages the user has left in PCB
  490.     bool           AliasSupport;       TRUE if Alias PSA installed
  491.     char           Alias[26];          Chosen Alias, if AliasSupport is TRUE
  492.     bool           AddressSupport;     TRUE if Address PSA installed
  493.     addresstypez   Address;            Address information, if AddressSupport is TRUE
  494.     bool           PasswordSupport;    TRUE if Password PSA installed
  495.     passwordtypez  PwrdHistory;        Password History, if PasswordSupport is TRUE
  496.     bool           VerifySupport;      TRUE if Verify PSA installed
  497.     char           Verify[26];         Verification Info, if VerifySupport is TRUE
  498.     bool           StatsSupport;       TRUE if Caller Stats PSA installed
  499.     callerstattype Stats;              Caller Stats, if StatsSupport is TRUE
  500.     bool           NotesSupport;       TRUE if Notes PSA installed
  501.     notestypez     Notes;              Notes about caller, if NotesSupport is TRUE
  502.     bool           AccountSupport;     TRUE if Accounting PSA installed
  503.     accounttype    Account;            Accounting values, if AccountSupport is TRUE
  504.     bool           QwkSupport;         TRUE if QWK/Net PSA installed
  505.     qwkconfigtype  QwkConfig;          QWK/Net values, if QwkSupport is TRUE
  506. |   double         TotDnldBytes;       "Live data" stored in IEEE Double format (replaces ulTotDnldBytes)
  507. |   double         TotUpldBytes;       "Live data" stored in IEEE Double format (replaces ulTotUpldBytes)
  508.   } userrectype;
  509.  
  510.   CHANGES FOR V15.0
  511.   -----------------
  512.   The fields near the end of the userrectype, from AliasSupport to Notes,
  513.   are new for v15.0.  This means that the record size has GROWN.  Those
  514.   applications which did not read the record size out of the header and jump
  515.   over any growth in the record size will fail.
  516.  
  517.   However, version 15.0 allows you to set the USERS.SYS setting in DOORS.LST
  518.   to either Y or O.  Setting it to Y tells PCBoard to create a native users.sys
  519.   file.  Setting it to 1 tells PCBoard to create the 'old' format .. that which
  520.   was used by PCBoard v14.5a.  This means that the additional information at
  521.   the end of the record will not be included.
  522.  
  523.   We recommend that you update your applications to properly deal with the
  524.   variable sized records so that they can be used with both v14.5a and v15.0
  525.   users.sys files.
  526.  
  527.   CHANGES FOR V15.2
  528.   -----------------
  529.   Once again, the USERS.SYS structure has GROWN.  The four new fields for
  530.   version 15.2 are AccountSupport, Account, QwkSupport and QwkConfig.
  531.  
  532.   To obtain a v15.0 format USERS.SYS file, use the number 2 inside DOORS.LST
  533.   under the USERS.SYS header.  A Y means create a default format (v15.2),
  534.   1 means to create a v14.5a format, and 2 means to create a v15.0 format.
  535.  
  536.   To ensure compatibility with all versions of PCBoard, you should ensure that
  537.   your software reads the header at the top of the USERS.INF file to determine
  538.   how big the structure is, then only read as much as your program knows
  539.   about, and also to determine how many bit fields there are since v15.2 has
  540.   one more bit field than v14.5 and v15.0 had.
  541.  
  542.  
  543.   LAST MESSAGE READ POINTERS
  544.   --------------------------
  545.   A LONG integer is used for each conference.  Therefore you must know the
  546.   number of conference areas (syshdrtype.NumOfAreas) to determine how many
  547.   long integers there are in the file (remember that the MAIN BOARD counts
  548.   as one conference area).
  549.  
  550.  
  551.   BIT MAPPED FIELDS
  552.   -----------------
  553.   A bit mapped field is nothing more than a string of bytes which when held
  554.   together can be searched to see if a specific BIT is turned on or off.
  555.  
  556.   You should read the header record syshdrtype.NumOfBitFields to determine
  557.   exactly how many bit fields there are in case a new release includes any
  558.   new fields (which you may skip over if you don't need them).
  559.  
  560.   There are currently 8 of these fields and they are in the following order:
  561.  
  562.   1) Registered in Conference
  563.   2) Expired Registered in Conference (same as above but used when expired)
  564.   3) User Scan in Conference (user preference for scanning conferences)
  565.   4) Conference Sysop (user gets Sysop Privileges while in conference)
  566.   5) Conference Mail (user has mail waiting in conference)
  567.   6) Conference Joined (user has already joined this conference today)
  568.   7) Conference Scanned (user has already scanned this conference today)
  569.   8) Conferences in which Net Status is available to th caller
  570.  
  571.   The actual size of each of these fields is given to you in the header
  572.   record syshdrtype.SizeOfBitFields.  You don't need to know this - but the
  573.   actual calculation of the size by PCBoard is made using the following
  574.   formula:
  575.  
  576.     ConfByteLen = (NumAreas / 8) + ((NumAreas % 8) != 0 ? 1 : 0);
  577.     if (ConfByteLen < 5)
  578.       ConfByteLen = 5;
  579.  
  580.   Basically, it allocates only the number of BYTES necessary to hold the
  581.   number of bits required for all of the conferences defined.  A minimum of
  582.   FIVE bytes are used due to PCBoard v14.0's conference definition of 40
  583.   conference areas.
  584.  
  585.   In other words, if you have only one conference there will be FIVE bytes
  586.   used due to v14.0's file layout requirements.  If you have 100 conferences
  587.   then there will be 13 bytes used (with 4 bits going unused).
  588.  
  589.   As you can see - bit mapped fields become almost a necessity with the fact
  590.   that there are currently 7 fields and a system may have as many as 65536
  591.   conferences (which if it weren't for bit mapped fields could prove to be a
  592.   very BIG file!).  With all 7 fields a system with 1024 conferences uses up
  593.   only 896 bytes - which if one byte per flag were used could have taken up
  594.   as much as 7168 bytes.
  595.  
  596.  
  597.   CALCULATING THE JULIAN DATE VALUES
  598.   ----------------------------------
  599.   The following calculations are used to calculate the LAST DATE ON and the
  600.   EXPIRATION DATE fields ..  it is a julian date calculation which is used so
  601.   that arithmetic performed on the date value itself will result in another
  602.   valid date.  In other words, "date + 365" equals a 365 days in the future.
  603.  
  604.     int Days[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
  605.  
  606.     date = 36525L * Year;
  607.     if ((date % 100) == 0 && Month < 3)
  608.       date--;
  609.  
  610.     date = (date - (1900 * 36525)) / 100;
  611.     date += Day + Days[Month-1];
  612.  
  613.  
  614.   Converting the julian date back into month, day and year values is a bit
  615.   trickier but is typically only done when displaying the date to the user or
  616.   storing it in the USERS file in "mmddyy" format.  The following calculations
  617.   can be used to convert the date back into the month, day and year components:
  618.  
  619.     int Days[2][12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
  620.                        0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
  621.  
  622.     Year  = (100 * Date) / 36525;
  623.     Temp  = Year * 36525L
  624.     Date -= Temp / 100;
  625.  
  626.     if (Temp % 100 == 0) {
  627.       Date++;
  628.       Leap = 1;
  629.     } else Leap = 0;
  630.  
  631.     for (Month = Counter = 0; Counter < 12; Counter++)
  632.       if (Days[Leap][Counter] < Date)
  633.         Month = Counter;
  634.  
  635.     Day = JD - Days[Leap][Month];
  636.  
  637.  
  638.   THIRD PARTY APPLICATION RECORD
  639.   ------------------------------
  640.   The Third Party Application record is used to hold information about the
  641.   USER which is specific to the application.  PCBoard copies this information
  642.   out of the USERS.INF file into the USERS.SYS file and then copies it back
  643.   upon reloading the software.  The advantage to letting PCBoard handle the
  644.   application needs is that as new users are added to the USERS file the
  645.   Third Party application records are created inside the USERS.INF file at
  646.   the same time.  And when a user is removed from the USERS file they are
  647.   also removed from the USERS.INF file at the same time (while third party
  648.   records are also being removed).
  649.  
  650.   The Third Party Application record is written in the USERS.SYS file
  651.   directly after the PCBoard Bit Map Fields.
  652.  
  653.   If a there are no installed Third Party Applications (or none which
  654.   required a user record) then the USERS.SYS file will end with the Bit
  655.   Mapped Fields described above.
  656.  
  657.   The way that PCBoard knows which Third Party Application record should be
  658.   appended to the USERS.SYS file is by the KEYWORD used by the caller to
  659.   invoke the application.
  660.  
  661.  
  662.   HANDLING THE USERS.SYS FILE
  663.   ---------------------------
  664.   The following information is in reference to how PCBoard expects the
  665.   USERS.SYS file to be handled by Third Party Applications.
  666.  
  667.   The USERS.SYS file is created as PCBoard is dropping to DOS and contains
  668.   what is basically a 'memory dump' of the values that PCBoard had in memory
  669.   at the time the caller dropped to DOS.
  670.  
  671.   On returning from DOS PCBoard will check to see if a USERS.SYS file is in the
  672.   \PCB directory REGARDLESS of whether or not a PCBOARD.SYS file existed or
  673.   indicated that a caller was online.
  674.  
  675.   If the Updated flag is set to TRUE (in this case the value must be a byte
  676.   value of 1 - no other value will be used to indicate TRUE so as to avoid
  677.   accidently specifying a TRUE response) then PCBoard will read in the rest
  678.   of the USERS.SYS file and update the USERS and USERS.INF files based on the
  679.   contents of the USERS.SYS file overwriting whatever previous values may have
  680.   been there.
  681.  
  682.   If the Updated flag is set to FALSE (the default) then it is assumed that
  683.   the TPA may have updated the USERS file directly (in the case of existing
  684.   v14.0 compatible programs) or that no modification was required.
  685.  
  686.   If the TPA allows the caller to hang up then it should clear the PCBOARD.SYS
  687.   file so that PCBoard will recycle.  PCBoard will still read the USERS.SYS
  688.   file which will indicate that a caller was, in fact, online and if the
  689.   Updated flag was set then it will still update the USERS and USERS.INF files.
  690.  
  691.   If the TPA updates the number of uploads, number of downloads or number of
  692.   messages left fields in USERS.SYS then PCBoard will properly determine that
  693.   such activity occured outside of the PCBoard environment and it will
  694.   properly update these statistics on the CALLWAITING screen without the use
  695.   of the PCBSTATS.EXE program.
  696.